﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using LimaLims.Application.Service.Base.Dto;
using LimaLims.Application.Service.Basic.Dto;
using LimaLims.Application.Service.Sys;
using LimaLims.Core.Entity.Basic;
using LimaLims.Core.Enum;
using LimaLims.Core;
using Microsoft.AspNetCore.Mvc;
using Mapster;
using Microsoft.EntityFrameworkCore;
using Furion.DatabaseAccessor.Extensions;
using Yitter.IdGenerator;

namespace LimaLims.Application.Service.Basic
{
    /// <summary>
    /// 项目服务
    /// </summary>
    [ApiDescriptionSettings(Name = "ProjectDrawing", Order = 166)]
    [Route("api")]
    public class ProjectDrawingService : IProjectDrawingService, IDynamicApiController, ITransient
    {
        private readonly IRepository<ProjectDrawing> _projectDrawingRep;  // 
        private readonly IRepository<Product> _productRep;  // 产品表仓储
        private readonly IGenerateCodeUtilService _generateCodeUtilService;//编码规则

        public ProjectDrawingService(IRepository<ProjectDrawing> projectRep, IRepository<Product> productRep, IGenerateCodeUtilService generateCode)
        {
            _projectDrawingRep = projectRep;
            _productRep = productRep;
            _generateCodeUtilService = generateCode;
        }

        /// <summary>
        /// 新增
        /// </summary>
        [HttpPost("projectDrawing/add")]
        public async Task Add(AddProjectDrawingInput input)
        {
            var isExist = await _projectDrawingRep.DetachedEntities.AnyAsync(u => u.Code == input.Code);
            if (isExist)
                throw Oops.Oh("已存在相同编号的原因！");

            if (string.IsNullOrWhiteSpace(input.Code))
            {
                input.Code = await _generateCodeUtilService.GenerateCode(BusinessType.Project);
            }

            var defectiveReason = input.Adapt<ProjectDrawing>();

            await defectiveReason.InsertAsync();
        }

        [HttpPost("projectDrawing/delete")]
        public async Task Delete(long id)
        {
            var project = await _projectDrawingRep.FirstOrDefaultAsync(u => u.Id == id);
            if (project == null)
                throw Oops.Oh("不存在此数据");

            var productCount = _productRep.DetachedEntities.Count(u => u.ProjectDrawingId == id);
            if (productCount > 0)
            {
                throw Oops.Oh($"{project.ProjectName}项目已经存在产品信息，请勿直接删除！");
            }
            await project.DeleteAsync();
        }

        [HttpGet("projectDrawing/detail")]
        public async Task<ProjectDrawing> Detail(long id)
        {
            var project = await _projectDrawingRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == id);
            if (project == null)
                throw Oops.Oh("不存在此数据");

            return project;
        }

        [HttpPost("projectDrawing/edit")]
        public async Task Edit(EditProjectDrawingInput input)
        {
            var project = await _projectDrawingRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
            if (project == null)
                throw Oops.Oh("不存在此数据！");

            var isExist = await _projectDrawingRep.DetachedEntities.AnyAsync(u => u.Code == input.Code && u.Id != input.Id);
            if (isExist)
                throw Oops.Oh("已存在相同编号的原因！");

            var projectModel = input.Adapt<ProjectDrawing>();

            await projectModel.UpdateAsync();
        }

        /// <summary>
        /// 下拉数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("projectDrawing/selectList")]
        public async Task<List<SelectDto>> SelectList()
        {
            var list = await _projectDrawingRep.DetachedEntities.Where(s => s.ValidStatus == true).OrderBy(s => s.Sort).ToListAsync();
            return list.Select(x => new SelectDto
            {
                Value = x.Id,
                Label = x.ProjectName
            }).ToList();
        }

        /// <summary>
        /// 生成产品信息
        /// </summary>
        [HttpGet("projectDrawing/generate")]
        [UnitOfWork]
        public async Task Generate(long id)
        {
            var project = await _projectDrawingRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == id);
            if (project == null)
                throw Oops.Oh("不存在此数据！");

            var productCount = _productRep.DetachedEntities.Count(u => u.ProjectDrawingId == id);
            if (productCount > 0)
            {
                throw Oops.Oh($"{project.ProjectName}项目已经存在产品信息，请勿重复生成！");
            }

            List<Product> products = new List<Product>();

            for (int i = 0; i < project.ProductCount; i++)
            {
                Product item = new Product
                {
                    Id = YitIdHelper.NextId(),
                    Code = await _generateCodeUtilService.GenerateCode(BusinessType.Product),
                    CategoryId = project.ProductCategoryId,
                    ProjectDrawingId = project.Id,
                    Name = project.ProducName,
                };
                products.Add(item);
            }
            await _productRep.InsertAsync(products);
        }



        [HttpGet("projectDrawing/page")]
        public async Task<PageResult<ProjectDrawingOutput>> QueryPage([FromQuery] ProjectDrawingPageInput input)
        {
            var searchValue = !string.IsNullOrEmpty(input.SearchValue?.Trim());
            var contractValue = !string.IsNullOrEmpty(input.ContractValue?.Trim());
            var items = await _projectDrawingRep.DetachedEntities
                                         .Where((searchValue, u => EF.Functions.Like(u.ProjectName, $"%{input.SearchValue.Trim()}%") || EF.Functions.Like(u.Code, $"%{input.SearchValue.Trim()}%")))
                                         .Where(input.ValidStatus.HasValue, u => u.ValidStatus == input.ValidStatus)
                                         .OrderBy(u => u.Sort)
                                         .Select(u => new ProjectDrawingOutput
                                         {
                                             Id = u.Id,
                                             Code = u.Code,
                                             ProjectName = u.ProjectName,
                                             PhaseNumber = u.PhaseNumber,
                                             ProducName = u.ProducName,
                                             ProductCategoryId = u.ProductCategoryId,
                                             ProductCount = u.ProductCount,
                                             ProductSymbol = u.ProductSymbol,
                                             CoolingMode = u.CoolingMode,
                                             HighVoltageRatedCurrent = u.HighVoltageRatedCurrent,
                                             HighVoltageRatedVoltage = u.HighVoltageRatedVoltage,
                                             LowVoltageRatedCurrent = u.LowVoltageRatedCurrent,
                                             LowVoltageRatedVoltage = u.LowVoltageRatedVoltage,
                                             Frequency = u.Frequency,
                                             InsulationClass = u.InsulationClass,
                                             Specification = u.Specification,
                                             RatedCapacity = u.RatedCapacity,
                                             Unit=u.Unit,
                                             ValidStatus = u.ValidStatus,
                                             Sort = u.Sort,
                                             CreatedTime = u.CreatedTime,
                                             CreatedUserName = u.CreatedUserName,
                                             UpdatedTime = u.UpdatedTime,
                                             UpdatedUserName = u.UpdatedUserName
                                         }).ToADPagedListAsync(input.PageNo, input.PageSize);

            return items;
        }
    }
}
